/*
Simple Forum Auto Poster.
Copyright (C) 2011 Gianni Van Hoecke.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package domain.forumdata;

import domain.enums.ForumType;
import java.util.Locale;

/**
 *
 * @author Gianni Van Hoecke <gianni.vh@gmail.com>
 * Static class with a set of handy forum utilities.
 */
public class ForumUtils
{
    public static final String[] USERNAME_SYNONYMS = new String[]{
                                                        "username",
                                                        "login_username",
                                                        "user",
                                                        "login",
                                                        "loginUsername",
                                                        "req_username",
                                                        "vb_login_username"};

    public static final String[] PASSWORD_SYNONYMS = new String[]{
                                                        "password",
                                                        "login_password",
                                                        "pass",
                                                        "passwrd",
                                                        "loginPassword",
                                                        "req_password",
                                                        "vb_login_password"};

    public static final String[] LOGIN_SUCCESS_SYNONYMS = new String[]{
                                                        "You have successfully logged in",
                                                        "You have been successfully logged in",
                                                        "You have successfully been logged in",
                                                        "Thank you for logging in",
                                                        "index.php?account/", //XenForo
                                                        "The login was successful",
                                                        "Show new replies to your posts",
                                                        "Logged in successfully",
                                                        "View your posts"};

    public static final String[] SUBJECT_SYNONYMS = new String[]{
                                                        "subject",
                                                        "topic_title",
                                                        "TopicTitle",
                                                        "req_subject",
                                                        "title"};

    public static final String[] DESCRIPTION_SYNONYMS = new String[]{
                                                        "description",
                                                        "topic_desc",
                                                        "TopicDesc",
                                                        "subtitle"};

    public static final String[] MESSAGE_SYNONYMS = new String[]{
                                                        "message",
                                                        "Post",
                                                        "text",
                                                        "req_message",
                                                        "postbody"};

    public static final String[] PREVIEW_SYNONYMS = new String[]{
                                                        "preview",
                                                        "previewpost"};

    public static final String[] POST_SUCCESS_SYNONYMS = new String[]{
                                                        "This message has been posted successfully",
                                                        "Your message has been entered successfully",
                                                        "Thank you, your thread has been posted",
                                                        "Post entered.",
                                                        "This message has been submitted successfully"};

    public static final String[] POST_SUCCESS_SMF_SYNONYMS = new String[]{
                                                        "index.php?topic=",
                                                        "new#new"};

    public static final String[] POST_SUCCESS_IPB3_SYNONYMS = new String[]{
                                                        "/index.php?/topic/"};

    public static final String[] POST_SUCCESS_XENFORO_SYNONYMS = new String[]{
                                                        "/index.php?threads/"};

    public static final String[] POST_SUCCESS_WOLTLAB_BB_SYNONYMS = new String[]{
                                                        "/index.php?page=Thread&threadID="};

    public static final String[] POST_SUCCESS_VBULLETIN_SYNONYMS = new String[]{
                                                        "showthread.php?",
                                                        "&p=",
                                                        "#post"};

    public static final String[] VIEW_TOPIC_INDICATOR = new String[]{
                                                        "./viewtopic.php?f=",
                                                        "viewtopic.php?p=",
                                                        "viewtopic.php?pid=",
                                                        "showthread.php?tid="};

    public static final String[] POST_SUCCESS_PHPBB3_SYNONYMS = new String[]{
                                                        "<span>Edit post</span>",
                                                        "Post a reply"};

    public static final String[] SAVE_DRAFT_SYNONYMS = new String[]{
                                                        "save",
                                                        "savedraft"};

    public static final String[] LAST_CLICK_SYNONYMS = new String[]{
                                                        "lastclick"};

    public static final String[] CREATION_TIME_SYNONYMS = new String[]{
                                                        "creation_time"};

    public static final String[] FORM_TOKEN_SYNONYMS = new String[]{
                                                        "form_token"};

    public static final String[] TOPIC_TYPE_SYNONYMS = new String[]{
                                                        "topic_type"};

    public static final String[] ICON_SYNONYMS = new String[]{
                                                        "icon",
                                                        "iconid"};

    public static final String[] POST_POLL_SYNONYMS = new String[]{
                                                        "postpoll",
                                                        "post_poll"};

    public static final String[] SEARCH_SYNONYMS = new String[]{
                                                        "Search"};

    public static final String[] LOCK_POST_SYNONYMS = new String[]{
                                                        "lock",
                                                        "check_lock"};

    public static final String[] RESET_SYNONYMS = new String[]{
                                                        "reset",
                                                        "clear"};

    /**
     * Checks whether the given field equals to any entry of the given synonyms or not.
     * @param field The field.
     * @param synonyms The synonyms.
     * @return True if there is a match, false otherwise.
     */
    private static boolean compare(String field, String[] synonyms)
    {
        for(String s : synonyms)
        {
            if(field.toLowerCase().equals(s.toLowerCase()))
                return true;
        }
        return false;
    }

    /**
     * Checks whether the given content is in any entry of the given synonyms or not.
     * The method uses the English locale to avoid special characters when doing a
     * toLowerCase.
     * @param content The content to search in.
     * @param synonyms The synonyms.
     * @return True if there's a match, false otherwise.
     */
    private static boolean compareContains(String content, String[] synonyms)
    {
        for(String s : synonyms)
        {
            if(content.toLowerCase(Locale.ENGLISH).contains(s.toLowerCase(Locale.ENGLISH)))
                return true;
        }
        return false;
    }

    /**
     * Checks whether the given content match all entries of the given synonyms or not.
     * The method uses the English locale to avoid special characters when doing a
     * toLowerCase.
     * @param content The content to search in.
     * @param synonyms The synonyms.
     * @param mustMatchAll True when all synonyms must occur in the content
     * @return True if there's a match, false otherwise.
     */
    private static boolean compareContains(String content, String[] synonyms, boolean mustMatchAll)
    {
        if(!mustMatchAll)
            return compareContains(content, synonyms);

        for(String s : synonyms)
        {
            if(!content.toLowerCase(Locale.ENGLISH).contains(s.toLowerCase(Locale.ENGLISH)))
                return false;
        }
        
        return true;
    }

    /**
     * Checks whether the given name is a username field or not.
     * @param name The name to check.
     * @return True if it is a username field, false otherwise.
     */
    public static boolean isUsernameField(String name)
    {
        return compare(name, USERNAME_SYNONYMS);
    }

    /**
     * Checks whether the given name is a password field or not.
     * @param name The name to check.
     * @return True if it is a password field, false otherwise.
     */
    public static boolean isPasswordField(String name)
    {
        return compare(name, PASSWORD_SYNONYMS);
    }

    /**
     * Checks whether the given name is a subject field or not.
     * @param name The name to check.
     * @return True if it is a subject field, false otherwise.
     */
    public static boolean isSubjectField(String name)
    {
        return compare(name, SUBJECT_SYNONYMS);
    }

    /**
     * Checks whether the given name is a description or subtitle field or not.
     * @param name The name to check.
     * @return True if it is a description or subtitle field, false otherwise.
     */
    public static boolean isDescriptionField(String name)
    {
        return compare(name, DESCRIPTION_SYNONYMS);
    }

    /**
     * Checks whether the given name is a message field or not.
     * @param name The name to check.
     * @return True if it is a message field, false otherwise.
     */
    public static boolean isMessageField(String name)
    {
        return compare(name, MESSAGE_SYNONYMS);
    }

    /**
     * Checks whether the given name is a preview field or not.
     * @param name The name to check.
     * @return True if it is a preview field, false otherwise.
     */
    public static boolean isPreviewField(String name)
    {
        return compare(name, PREVIEW_SYNONYMS);
    }

    /**
     * Checks whether the login is succesful or not.
     * @param content The content to check.
     * @return True if the login is succesful, false otherwise.
     */
    public static boolean isLoginSuccessful(String content)
    {
        return compareContains(content, LOGIN_SUCCESS_SYNONYMS);
    }

    /**
     * Checks whether the post is succesful or not.
     * @param content The content to check.
     * @return True if the post is succesful, false otherwise.
     */
    public static boolean isPostSuccessful(String content)
    {
        return compareContains(content, POST_SUCCESS_SYNONYMS);
    }

    /**
     * Checks whether the post is succesful or not, when dealing with SMF.
     * @param content The content to check.
     * @return True if the post is succesful, false otherwise.
     */
    public static boolean isPostSuccessful(String url, ForumType forumType)
    {
        switch(forumType)
        {
            case OTHER:
            default:
                return ForumUtils.isPostSuccessful(url);
            case SMF:
                return compareContains(url, POST_SUCCESS_SMF_SYNONYMS, true);
            case VBULLETIN:
                return compareContains(url, POST_SUCCESS_VBULLETIN_SYNONYMS, true);
            case IPB3:
                return compareContains(url, POST_SUCCESS_IPB3_SYNONYMS, true);
            case XENFORO:
                return compareContains(url, POST_SUCCESS_XENFORO_SYNONYMS, true);
            case WOLTLAB_BURNING_BOARD:
                return compareContains(url, POST_SUCCESS_WOLTLAB_BB_SYNONYMS, true);
            case PHPBB3:
                return compareContains(url, POST_SUCCESS_PHPBB3_SYNONYMS, true);
        }
    }

    /**
     * Checks whether the given name is a view topic indicator.
     * @param name The name to check.
     * @return True if it is a view topic indicator, false otherwise.
     */
    public static boolean isViewTopicIndocator(String href)
    {
        return compareContains(href, VIEW_TOPIC_INDICATOR);
    }

    /**
     * Checks whether the given name is a 'Save draft' indicator.
     * @param name The name to check.
     * @return True if it is a 'Save draft' indicator, false otherwise.
     */
    public static boolean isSaveDraftField(String name)
    {
        return compare(name, SAVE_DRAFT_SYNONYMS);
    }

    /**
     * Checks whether the given name is a last click field.
     * @param name The name to check.
     * @return True if it is a last click field, false otherwise.
     */
    public static boolean isLastClickField(String name)
    {
        return compare(name, LAST_CLICK_SYNONYMS);
    }

    /**
     * Checks whether the given name is a creation time field.
     * @param name The name to check.
     * @return True if it is a creation time field, false otherwise.
     */
    public static boolean isCreationTimeField(String name)
    {
        return compare(name, CREATION_TIME_SYNONYMS);
    }

    /**
     * Checks whether the given name is a form token field.
     * @param name The name to check.
     * @return True if it is a form token field, false otherwise.
     */
    public static boolean isFormTokenField(String name)
    {
        return compare(name, FORM_TOKEN_SYNONYMS);
    }

    /**
     * Checks whether the given name is a topic type field.
     * @param name The name to check.
     * @return True if it is a topic type field, false otherwise.
     */
    public static boolean isTopicTypeField(String name)
    {
        return compare(name, TOPIC_TYPE_SYNONYMS);
    }

    /**
     * Checks whether the given name is an icon field.
     * @param name The name to check.
     * @return True if it is an icon field, false otherwise.
     */
    public static boolean isIconField(String name)
    {
        return compare(name, ICON_SYNONYMS);
    }

    /**
     * Checks whether the given name is a post poll field.
     * @param name The name to check.
     * @return True if it is a post poll field, false otherwise.
     */
    public static boolean isPostPollField(String name)
    {
        return compare(name, POST_POLL_SYNONYMS);
    }

    /**
     * Checks whether the given name is a search field.
     * @param value The value to check.
     * @return True if it is a search field, false otherwise.
     */
    public static boolean isSearchField(String value)
    {
        return compare(value, SEARCH_SYNONYMS);
    }

    /**
     * Checks whether the given name is a lock post field.
     * @param value The value to check.
     * @return True if it is a lock post field, false otherwise.
     */
    public static boolean isLockPostField(String value)
    {
        return compare(value, LOCK_POST_SYNONYMS);
    }

    /**
     * Checks whether the given name is a reset field.
     * @param value The value to check.
     * @return True if it is a reset field, false otherwise.
     */
    public static boolean isResetField(String value)
    {
        return compare(value, RESET_SYNONYMS);
    }
}